<template>
  <div style="padding: 5px">
    <div style="width: 300px; float:left">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" style="text-align:center">
            <span>源数据库信息</span>
          </div>
        </template>
        <div class="text item">
          <el-tree
            :data="odsDbTree"
            :props="defaultProps"
            node-key="id"
            accordion
            highlight-current
            :default-expanded-keys="defaultExpandedkeys"
            @node-click="handleNodeClick"
          >
            <template #default="{ data, node }">
              <div class="custom-tree-node">
                <el-button v-if="data.inOds" type="success" style="float: left" size="small">{{ node.label }}</el-button>
                <el-button v-if="!data.inOds" type="default" style="float: left" size="small">{{ node.label }}</el-button>
              </div>
            </template>
          </el-tree>
        </div>
      </el-card>
    </div>

    <div>
      <el-card
        :body-style="{ padding: '5px' }"
        class="box-card"
      >
        <template #header>
          <div class="card-header" style="text-align:center">
            <span>源数据库表信息</span>
          </div>
        </template>

        <el-row v-if="odsDbSchema != ''">
          <el-col>
            <el-button icon="CaretBottom" size="small" type="info" style="float: left">源库信息</el-button>
          </el-col>
          <el-col>
            <el-form
              ref="elFormSchema"
              class="x-form"
              :model="odsDb"
              label-position="right"
              :rules="ruleOdsSchema"
              :inline="true"
            >
              <el-form-item label="源数据类型:" prop="dbType">
                <el-input v-model="odsDb.dbType" :disabled="true" />
              </el-form-item>
              <el-form-item label="源数据主题:" prop="dbTopic">
                <el-input v-model="odsDb.dbTopic" />
              </el-form-item>
              <el-form-item label="源数据库ip:" prop="dbIp">
                <el-input v-model="odsDb.dbIp" :disabled="true" />
              </el-form-item>
              <el-form-item label="源数据库端口:" prop="dbPort">
                <el-input v-model="odsDb.dbPort" :disabled="true" />
              </el-form-item>
              <el-form-item label="源数据库名:" prop="schemaName">
                <el-input v-model="odsDbSchema" :disabled="true" />
              </el-form-item>
            </el-form>
          </el-col>
        </el-row>

        <el-row v-if="Object.keys(odsDbTb).length">
          <el-col>
            <el-button icon="CaretBottom" size="small" type="info" style="float: left">源表信息</el-button>
            <el-button v-if="odsDbTb.ID === 0" icon="plus" size="small" type="primary" style="float: left" @click="clickCreateOdsDbConfig">入 库</el-button>
            <el-button v-if="odsDbTb.ID > 0" icon="refresh" size="small" type="primary" style="float: left" @click="clickUpdateOdsDbTb">保 存</el-button>
            <el-button v-if="odsDbTb.ID > 0" icon="delete" size="small" type="warning" style="float: left" @click="clickDeleteOdsDbConfig">删除表</el-button>
          </el-col>
          <el-col>
            <el-form
              ref="elFormTb"
              class="x-form"
              :model="odsDbTb"
              label-position="right"
              :rules="ruleOdsTb"
              :inline="true"
            >
              <el-form-item label="ods表id:" prop="ID">
                <el-input v-model="odsDbTb.ID" :disabled="true" />
              </el-form-item>
              <el-form-item label="源数据表名:" prop="srcTbName">
                <el-input v-model="odsDbTb.srcTbName" :disabled="true" />
              </el-form-item>
              <el-form-item label="ods库名:" prop="odsSchemaName">
                <el-select v-model="odsDbTb.odsSchemaName" style="width:600px">
                  <el-option v-for="item in odsDbSchemaList" :key="item.id" :value="item.label" :label="item.label" />
                </el-select>
              </el-form-item>
              <el-form-item label="ods表名:" prop="odsTbName">
                <el-input v-model="odsDbTb.odsTbName" :disabled="true" />
              </el-form-item>
              <el-form-item label="ods表标签:" prop="odsTbLabel">
                <el-input v-model="odsDbTb.odsTbLabel" />
              </el-form-item>
              <el-form-item label="主键列名:" prop="priCol">
                <el-select v-model="odsDbTb.priCol" style="width:600px" clearable>
                  <el-option v-for="item in tbColsList" :key="item" :value="item" :label="item" />
                </el-select>
              </el-form-item>
              <el-form-item label="唯一值列名:" prop="uniCol">
                <el-select v-model="odsDbTb.uniCol" style="width:600px" clearable>
                  <el-option v-for="item in tbColsList" :key="item" :value="item" :label="item" />
                </el-select>
              </el-form-item>
            </el-form>
          </el-col>
        </el-row>

        <el-row v-if="Object.keys(odsDbJob).length">
          <el-col>
            <el-button icon="CaretBottom" size="small" type="info" style="float: left">同步设置</el-button>
            <el-button icon="refresh" size="small" type="primary" style="float: left;" @click="clickUpdateOdsDbJob">保 存</el-button>
            <el-button v-if="getJobRunning(odsDbJob.odsTbName)=== '未运行' && odsDbJob.ready === 1 && odsDbJob.start === true" icon="caretRight" size="small" type="primary" style="float: left;" @click="clickStartOdsDbJob()">启 动</el-button>
            <el-button v-if="getJobRunning(odsDbJob.odsTbName)=== '运行中'" icon="removeFilled" size="small" type="primary" style="float: left;" @click="clickStopOdsDbJob">停 止</el-button>
          </el-col>
          <el-col>
            <el-form
              ref="elFormJob"
              class="x-form"
              :model="odsDbJob"
              label-position="right"
              :rules="ruleOdsJob"
              :inline="true"
            >
              <el-form-item label="ods表id:" prop="odsDbTbId">
                <el-input v-model="odsDbJob.odsTbId" :disabled="true" />
              </el-form-item>
              <el-form-item label="任务中文名:" prop="jobName">
                <el-input v-model="odsDbJob.jobName" />
              </el-form-item>
              <el-form-item label="任务类型:" prop="jobType">
                <el-select v-model="odsDbJob.jobType" style="width:600px">
                  <el-option v-for="item in dictJobType" :key="item.id" :value="item.label" :label="item.label" />
                </el-select>
              </el-form-item>
              <el-form-item label="同步方式:" prop="syncType">
                <el-select v-model="odsDbJob.syncType" style="width:600px" clearable>
                  <el-option v-for="item in dictSyncType" :key="item.id" :value="item.label" :label="item.label" />
                </el-select>
              </el-form-item>
              <template v-if="odsDbJob.jobType==='定时同步' || odsDbJob.jobType==='周期同步'">
                <el-form-item label="同步列名称:" prop="syncColName" :rules="odsDbJob.syncType === '增量同步'?{required:true,message:'增量同步时必填',trigger:'blur'}:{required:false}">
                  <el-select v-model="odsDbJob.syncColName" style="width:600px">
                    <el-option v-for="item in tbColsList" :key="item" :value="item" :label="item" />
                  </el-select>
                </el-form-item>
                <el-form-item label="cron表达式:" prop="cronExpression" :rules="odsDbJob.syncType === '增量同步'?{required:true,message:'增量同步时必填',trigger:'blur'}:{required:false}">
                  <el-input v-model="odsDbJob.cronExpression" />
                </el-form-item>
              </template>
              <el-form-item label="同步步长:" prop="step">
                <el-input v-model="odsDbJob.step" @blur="odsDbSync.step=Number(odsDbSync.step)" />
              </el-form-item>
              <el-form-item label="同步范围语句:" prop="scopeString">
                <el-input v-model="odsDbJob.scopeString" placeholder="默认全量同步" />
              </el-form-item>
              <el-form-item label="最大同步数量:" prop="syncLimit">
                <el-input v-model="odsDbJob.syncLimit" placeholder="单次最大同步行数" />
              </el-form-item>
              <el-form-item label="是否运行:" prop="isRunning">
                <a style="width: 193px">{{getJobRunning(odsDbJob.odsTbName)}}</a>
              </el-form-item>
              <el-form-item label="是否启动:" prop="start">
                <el-switch v-model="odsDbJob.start" active-color="#13ce66" inactive-color="#ff4949" active-text="是" inactive-text="否" clearable />
              </el-form-item>
            </el-form>
          </el-col>
        </el-row>

        <el-row v-if="odsDbFlds.length > 0">
          <el-col>
            <el-button v-if="fldsData.length>0" icon="CaretBottom" size="small" type="info" style="float: left">字段内容</el-button>
          </el-col>
          <el-col>
            <el-table
              v-if="fldsData.length>0"
              ref="multipleTable"
              :key="refresh"
              style="width: 100%"
              tooltip-effect="dark"
              :data="fldsData "
              row-key="ID"
              border
              :header-cell-style="{background:'#a3c6d2',color:'#849ba1'}"
              size="small"
              :row-style="{height:'20px'}"
              :cell-style="{padding:'0px'}"
              :show-header="false"
            >
              <el-table-column
                v-for="(v,k) in fldsData[0]"
                :key="k"
                :prop="k"
                :label="k"
                align="left"
                :show-overflow-tooltip="true"
              />
            </el-table>
          </el-col>
        </el-row>
      </el-card>
    </div>
  </div>
</template>

<script setup>
import { reactive, ref, onMounted } from 'vue'
import defaultProps from 'element-plus/es/components/table/src/table-body/defaults'
import { ElMessage } from 'element-plus'
import {
  getOdsDbTree,
  getOdsDbConfig,
  createOdsDbConfig,
  deleteOdsDbConfig,
  startOdsDbJob, stopOdsDbJob,
} from '@/api/odsDbConfig'
import { getDict } from '@/utils/dictionary'
import { updateOdsDbTable } from '@/api/odsDbTable'
import { findOdsJob, getOdsJobRunning, updateOdsJob } from '@/api/odsJob'

const odsDbTree = ref([{ label: '没有数据源' }])
const defaultExpandedkeys = ref([])
const odsDb = ref({})
const odsDbSchema = ref('')
const odsDbTb = ref({})
const odsDbFlds = ref([])
const fldsData = ref([])
const odsDbJob = ref({})
const jobRunning = ref([])
const dictSyncType = ref([])
const dictJobType = ref([])
const odsDbConfig = ref({
  'odsDbTb': odsDbTb.value,
  'odsDbFlds': odsDbFlds.value,
  'odsDbJob': odsDbJob.value,
})
const odsDbConfig_set = () => {
  odsDbConfig.value = {
    'odsDbTb': odsDbTb.value,
    'odsDbFlds': odsDbFlds.value,
    'odsDbJob': odsDbJob.value,
  }
}
const getJobRunning = (tbName) => {
  if (jobRunning.value.length > 0) {
    const isExist = jobRunning.value.indexOf(tbName)
    if (isExist >= 0) {
      return '运行中'
    } else {
      return '未运行'
    }
  } else {
    return '未运行'
  }
}
const odsDb_Reset = () => {
  odsDb.value = {}
}
const odsDbSchema_Reset = () => {
  odsDbSchema.value = ''
}
const odsDbTb_Reset = () => {
  odsDbTb.value = {}
}
const odsDbFlds_Reset = () => {
  odsDbFlds.value = []
}
const odsDbJob_Reset = () => {
  odsDbJob.value = {}
}

const fldData_Reset = () => {
  fldsData.value = []
}

const ruleOdsSchema = reactive({
  dbType: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
  dbTopic: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
  dbIp: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
  dbPort: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
  schemaName: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
})
const ruleOdsTb = reactive({
  srcSchema: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
  srcTbName: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
  odsSchemaName: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
  odsTbLabel: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
})

const ruleOdsJob = reactive({
  jobName: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
  jobType: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
  syncType: [{
    required: true,
    message: '',
    trigger: ['input', 'blur'],
  }],
})

const refresh = ref(true)

const tbColsList = ref([])

const handleNodeClick = async(data) => {
  if (data.type === 'odsDb') {
    odsDb_Reset()
    odsDb.value = data.odsDb
    odsDbSchema_Reset()
    odsDbTb_Reset()
    odsDbFlds_Reset()
    odsDbJob_Reset()
    fldData_Reset()
    refreshTreeTb()
    return
  }
  if (data.type === 'odsDbSchema') {
    odsDbSchema_Reset()
    odsDbSchema.value = data.label
    odsDbTb_Reset()
    odsDbFlds_Reset()
    odsDbJob_Reset()
    fldData_Reset()
    refreshTreeTb()
    return
  }
  if (data.type === 'odsDbTb') {
    odsDbTb_Reset()
    odsDbTb.value = data.odsDbTb

    odsDbConfig_set()
    const res = await getOdsDbConfig(odsDbConfig.value)
    if (res.code === 0) {
      odsDbTb_Reset()
      odsDbTb.value = res.data.odsDbTb
      tbColsList.value = []
      tbColsList.value = odsDbTb.value.colsString.split(',')

      odsDbFlds_Reset()
      odsDbFlds.value = res.data.odsDbFlds

      odsDbJob_Reset()
      odsDbJob.value = res.data.odsDbJob

      fldData_Reset()
      fldsData.value = res.data.fldsData
    }
    const res1 = await getOdsJobRunning()
    if (res1.code === 0) {
      jobRunning.value = res1.data.jobRunning
    }
  }
}

const refreshTreeTb = () => {
  for (let d = 0; d < odsDbTree.value.length; d++) {
    for (let s = 0; s < odsDbTree.value[d].children.length; s++) {
      let ss = 0
      for (let t = 0; t < odsDbTree.value[d].children[s].children.length; t++) {
        if (odsDbTree.value[d].children[s].children[t].inOds === 1) {
          ss++
        }
      }
      if (ss > 0) {
        odsDbTree.value[d].children[s].inOds = 1
      } else {
        odsDbTree.value[d].children[s].inOds = 0
      }
    }
  }
}
const clearTreeTb = () => {
  for (let d = 0; d < odsDbTree.value.length; d++) {
    if (odsDb.value.dbTopic === odsDbTree.value[d].label) {
      for (let s = 0; s < odsDbTree.value[d].children.length; s++) {
        if (odsDbSchema.value === odsDbTree.value[d].children[s].label) {
          for (let t = 0; t < odsDbTree.value[d].children[s].children.length; t++) {
            if (odsDbTb.value.srcTbName === odsDbTree.value[d].children[s].children[t].label) {
              odsDbTree.value[d].children[s].children[t].inOds = 0
            }
          }
        }
      }
    }
  }
}

const setTreeTb = () => {
  for (let d = 0; d < odsDbTree.value.length; d++) {
    if (odsDb.value.dbTopic === odsDbTree.value[d].label) {
      for (let s = 0; s < odsDbTree.value[d].children.length; s++) {
        if (odsDbSchema.value === odsDbTree.value[d].children[s].label) {
          for (let t = 0; t < odsDbTree.value[d].children[s].children.length; t++) {
            if (odsDbTb.value.srcTbName === odsDbTree.value[d].children[s].children[t].label) {
              odsDbTree.value[d].children[s].children[t].inOds = 1
            }
          }
        }
      }
    }
  }
}

const elFormTb = ref()
const clickCreateOdsDbConfig = async() => {
  elFormTb.value?.validate(async(valid) => {
    if (!valid) {
      ElMessage({
        type: 'warning',
        message: '请填写完整'
      })
      return
    }
    odsDbConfig_set()
    const res = await createOdsDbConfig(odsDbConfig.value)
    if (res.code === 0) {
      odsDbTb.value = res.data.odsDbTb
      odsDbFlds.value = res.data.odsDbFlds
      odsDbJob.value = res.data.odsDbJob
      fldsData.value = res.data.fldsData
      setTreeTb()
      refreshTreeTb()
      ElMessage({
        type: 'success',
        message: res.msg
      })
    }
  })
}
const clickDeleteOdsDbConfig = async() => {
  if (odsDbTb.value) {
    odsDbConfig_set()
    const res = await deleteOdsDbConfig(odsDbConfig.value)
    if (res.code === 0) {
      clearTreeTb()
      refreshTreeTb()
      odsDbTb.value.ID = 0
      odsDbJob.value = {}
      ElMessage({
        type: 'success',
        message: res.msg
      })
    } else {
    }
  }
}

const clickUpdateOdsDbTb = async() => {
  if (odsDbTb.value) {
    const res = await updateOdsDbTable(odsDbTb.value)
    if (res.code === 0) {
      ElMessage({
        type: 'success',
        message: res.msg
      })
    }
  }
}

const clickUpdateOdsDbJob = async() => {
  if (odsDbTb.value) {
    const res = await updateOdsJob(odsDbJob.value)
    if (res.code === 0) {
      ElMessage({
        type: 'success',
        message: res.msg
      })
      const resj = await findOdsJob({ ID: odsDbJob.value.ID })
      if (resj.code === 0) {
        odsDbJob.value = resj.data.reodsJob
      }
    }
  }
}

const clickStartOdsDbJob = async() => {
  const res = await startOdsDbJob(odsDbJob.value)
  if (res.code === 0) {
    const resj = await findOdsJob({ ID: odsDbJob.value.ID })
    if (resj.code === 0) {
      odsDbJob.value = resj.data.reodsJob
    }
  }

  const res1 = await getOdsJobRunning()
  if (res1.code === 0) {
    jobRunning.value = res1.data.jobRunning
  }
}
const clickStopOdsDbJob = async() => {
  const res = await stopOdsDbJob(odsDbJob.value)
  if (res.code === 0) {
    odsDbJob.value.inTimer = 0
  }

  const res1 = await getOdsJobRunning()
  if (res1.code === 0) {
    jobRunning.value = res1.data.jobRunning
  }
}

const asyncOdsDbTree = async() => {
  const res = await getOdsDbTree()
  if (res.code === 0) {
    odsDbTree.value = res.data.odsDbTree
    refresh.value = !refresh.value
  } else {
    ElMessage({
      type: 'warning',
      message: res.msg
    })
  }
}

const odsDbSchemaList = ref([])
const getDictConfig = async() => {
  odsDbSchemaList.value = await getDict('odsSchemaList')
  dictSyncType.value = await getDict('syncType')
  dictJobType.value = await getDict('jobType')
}

const init = async() => {
  await getDictConfig()
  await asyncOdsDbTree()
}
onMounted(async() => {
  await init()
})
</script>

<script>
export default {
  name: 'OdsDbConfig'
}
</script>

<style scoped lang="scss">
.previewCodeTool {
  display: flex;
  align-items: center;
  padding: 5px 0;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.button-box {
  padding: 10px 20px;

  .el-button {
    margin-right: 20px;
    float: right;
  }
}

.auto-btn-list {
  margin-top: 16px;
}

.auto-icon {
  margin-left: 6px;
  color: #666;
  cursor: pointer;
}

.box {
  width: 100%;
  height: 22px;
  display: flex;
  flex-direction: row;
}

.box > div {
  height: 22px;
  flex: 1;
}

.el-col-12 {
  width: 15%;
}

.el-card-define {
  min-height: 100%;
  height: 100%;
}

.el-card-define.el-card__body {
  height: 100%;
}

.el-table:deep(thead) {
  color: #fff;
  font-weight: 500;
  background: linear-gradient(to right, #6fa3fe, #4cdafe) !important;

  & th {
    background-color: transparent;
  }

  & tr {
    background-color: transparent;
  }

}

.tb-clr-liner {
  background: linear-gradient(to right, #EAE5C9, #6CC6CB);
}

.bodyDiv {
  background: linear-gradient(to right, #EAE5C9, #6CC6CB);
}

.el-card:deep(.el-card__header) {
  background: linear-gradient(to bottom, #98c6ec, #f6f8f7);
}

.el-table:deep(.el-table__header) {
  background: linear-gradient(to right, #98c6ec, #e2f3ef);
}
</style>
